#pragma once

#include <thread>
#include <mutex>
#include <atomic>
#include <memory>

#include <windows.h>

using namespace std;

#define WM_USER_REFRESH (WM_USER + 1)

LRESULT CALLBACK DisplayWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

class CDisplayBase
{
public:
	enum RENDER_STATE : int
	{
		FREE,
		LOADING,
		WORKING
	};

public:
	CDisplayBase();

	virtual ~CDisplayBase();

public:
	virtual void CreateDisplayWindow(int left, int top, int width, int height);

	virtual LRESULT WindowMessageProc(UINT uMsg, WPARAM wParam, LPARAM lParam);

	virtual void ReshapeWindow(int nwidth, int nheight);

	virtual void Display(HDC hDc);

public:
	void ForceRefresh();

	void CloseAndWaitWindowClosed();

	RENDER_STATE GetDisplayState();

protected:
	bool InitWindowInner(int left, int top, int width, int height);

	void WindowLoop();

protected:
	std::atomic<RENDER_STATE> m_RenderState;

	std::shared_ptr<std::thread> m_pRenderThread;
	std::mutex m_CvLock;
	std::condition_variable m_InitCv;

	HWND m_WindowHandle;

	int m_WindowWidth;
	int m_WindowHeight;
};
